import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

// 上传任务状态
export enum UploadStatus {
  WAITING = 'waiting',
  UPLOADING = 'uploading',
  SUCCESS = 'success',
  ERROR = 'error',
  CANCELED = 'canceled'
}

// 上传任务接口
export interface UploadTask {
  id: string
  file: File
  fileName: string
  fileSize: number
  parentId: number
  status: UploadStatus
  progress: number
  speed: number
  remainingTime: number
  errorMessage?: string
  xhr?: XMLHttpRequest
  startTime?: number
  uploadedBytes: number
}

export const useUploadStore = defineStore('upload', () => {
  // 状态
  const tasks = ref<UploadTask[]>([])
  const isDialogVisible = ref(false)
  const maxConcurrent = ref(3) // 最大并发上传数

  // 计算属性
  const uploadingTasks = computed(() =>
    tasks.value.filter(task => task.status === UploadStatus.UPLOADING)
  )

  const completedTasks = computed(() =>
    tasks.value.filter(task =>
      task.status === UploadStatus.SUCCESS || task.status === UploadStatus.ERROR
    )
  )

  const totalProgress = computed(() => {
    if (tasks.value.length === 0) return 0
    const totalSize = tasks.value.reduce((sum, task) => sum + task.fileSize, 0)
    const uploadedSize = tasks.value.reduce((sum, task) => sum + task.uploadedBytes, 0)
    return Math.round((uploadedSize / totalSize) * 100)
  })

  const isUploading = computed(() => uploadingTasks.value.length > 0)

  // 生成唯一ID
  const generateTaskId = () => {
    return Date.now().toString() + Math.random().toString(36).substr(2, 9)
  }

  // 添加上传任务
  const addTask = (file: File, parentId: number): string => {
    const taskId = generateTaskId()
    const task: UploadTask = {
      id: taskId,
      file,
      fileName: file.name,
      fileSize: file.size,
      parentId,
      status: UploadStatus.WAITING,
      progress: 0,
      speed: 0,
      remainingTime: 0,
      uploadedBytes: 0
    }

    tasks.value.push(task)

    // 自动开始上传如果并发数允许
    startNextUpload()

    return taskId
  }

  // 更新任务状态
  const updateTask = (taskId: string, updates: Partial<UploadTask>) => {
    const task = tasks.value.find(t => t.id === taskId)
    if (task) {
      Object.assign(task, updates)
    }
  }

  // 移除任务
  const removeTask = (taskId: string) => {
    const index = tasks.value.findIndex(t => t.id === taskId)
    if (index > -1) {
      tasks.value.splice(index, 1)
    }
  }

  // 取消任务
  const cancelTask = (taskId: string) => {
    const task = tasks.value.find(t => t.id === taskId)
    if (task) {
      if (task.xhr) {
        task.xhr.abort()
      }
      task.status = UploadStatus.CANCELED
      startNextUpload()
    }
  }

  // 重试任务
  const retryTask = (taskId: string) => {
    const task = tasks.value.find(t => t.id === taskId)
    if (task && task.status === UploadStatus.ERROR) {
      task.status = UploadStatus.WAITING
      task.progress = 0
      task.uploadedBytes = 0
      task.errorMessage = undefined
      task.xhr = undefined
      startNextUpload()
    }
  }

  // 开始下一个上传任务
  const startNextUpload = () => {
    const uploadingCount = uploadingTasks.value.length
    if (uploadingCount >= maxConcurrent.value) return

    const waitingTask = tasks.value.find(task => task.status === UploadStatus.WAITING)
    if (waitingTask) {
      waitingTask.status = UploadStatus.UPLOADING
      waitingTask.startTime = Date.now()
    }
  }

  // 计算上传速度和剩余时间
  const updateProgress = (taskId: string, loaded: number, total: number) => {
    const task = tasks.value.find(t => t.id === taskId)
    if (!task || !task.startTime) return

    const now = Date.now()
    const elapsed = (now - task.startTime) / 1000 // 秒
    const progress = Math.round((loaded / total) * 100)
    const speed = loaded / elapsed // bytes/second
    const remainingBytes = total - loaded
    const remainingTime = speed > 0 ? remainingBytes / speed : 0

    updateTask(taskId, {
      progress,
      speed,
      remainingTime,
      uploadedBytes: loaded
    })
  }

  // 显示上传对话框
  const showDialog = () => {
    isDialogVisible.value = true
  }

  // 隐藏上传对话框
  const hideDialog = () => {
    isDialogVisible.value = false
  }

  // 清空已完成任务
  const clearCompletedTasks = () => {
    tasks.value = tasks.value.filter(task =>
      task.status !== UploadStatus.SUCCESS && task.status !== UploadStatus.ERROR
    )
  }

  // 清空所有任务
  const clearAllTasks = () => {
    // 取消所有进行中的任务
    uploadingTasks.value.forEach(task => {
      if (task.xhr) {
        task.xhr.abort()
      }
    })
    tasks.value = []
  }

  // 格式化文件大小
  const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 B'
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  // 格式化速度
  const formatSpeed = (bytesPerSecond: number): string => {
    return formatFileSize(bytesPerSecond) + '/s'
  }

  // 格式化时间
  const formatTime = (seconds: number): string => {
    if (seconds === 0 || !isFinite(seconds)) return '--'

    const hours = Math.floor(seconds / 3600)
    const minutes = Math.floor((seconds % 3600) / 60)
    const secs = Math.floor(seconds % 60)

    if (hours > 0) {
      return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
    }
    return `${minutes}:${secs.toString().padStart(2, '0')}`
  }

  return {
    // 状态
    tasks,
    isDialogVisible,
    maxConcurrent,

    // 计算属性
    uploadingTasks,
    completedTasks,
    totalProgress,
    isUploading,

    // 方法
    addTask,
    updateTask,
    removeTask,
    cancelTask,
    retryTask,
    startNextUpload,
    updateProgress,
    showDialog,
    hideDialog,
    clearCompletedTasks,
    clearAllTasks,

    // 工具方法
    formatFileSize,
    formatSpeed,
    formatTime
  }
})